package edu.tsinghua.mrpvc.device.frige;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Hashtable;
import java.util.Map;

import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.service.event.EventHandler;
import org.osgi.util.tracker.ServiceTracker;

import edu.tsinghua.mrpvc.device.FrigeDevice;
import edu.tsinghua.mrpvc.device.simulate.FrigeSimulateTopic;


public class FrigeDeviceImpl implements FrigeDevice, EventHandler {

	private float tmp;
	private String ID;
	private BundleContext context;
	private ServiceTracker tracker;
	private ArrayList<String> foodInfo = new ArrayList<String>(); 
	
	public FrigeDeviceImpl(BundleContext context, String ID){
		this.context = context;
		this.ID = ID;
		this.tmp = 10;
		tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
		tracker.open();
		foodInfo.add("Cabbage");
		foodInfo.add("Tomato");
		foodInfo.add("Potato");
		foodInfo.add("Fish");
		foodInfo.add("Chicken");
	}
	
	@Override
	public float downTemperature() {
		// TODO Auto-generated method stub
		tmp -= INCREMENT;
		return tmp;
	}

	@Override
	public float getTemperature() {
		// TODO Auto-generated method stub
		return tmp;
	}

	@Override
	public int play(String path) {
		// TODO Auto-generated method stub
		return 1;
	}

	@Override
	public float setTemperature(float tmp) {
		// TODO Auto-generated method stub
		this.tmp = tmp;
		return tmp;
	}

	@Override
	public float upTemperature() {
		// TODO Auto-generated method stub
		tmp += INCREMENT;
		return tmp;
	}

	@Override
	public String getID() {
		// TODO Auto-generated method stub
		return ID;
	}

	@Override
	public boolean isValid() {
		// TODO Auto-generated method stub
		return true;
	}

	private void generStateEvent(){
		EventAdmin eventAdmin = (EventAdmin) tracker.getService();
		if(eventAdmin != null){
			System.out.println(Calendar.getInstance().getTime().toLocaleString() +
					" Frige: state changed and post event");
			Map<String, Object> proper = new Hashtable<String, Object>();
			proper.put(FrigeDevice.EVENT_PROPER_ID, ID);
			proper.put(FrigeDevice.EVENT_PROPER_TMP, Float.toString(tmp));
			proper.put(FrigeDevice.EVENT_PROPER_FOOD_NAME, foodInfo.toArray(new String[foodInfo.size()]));
			Event event = new Event(FrigeDevice.EVENT_TOPIC_STATE, proper);
			eventAdmin.postEvent(event);
		}		
	}
	@Override
	public void handleEvent(Event event) {
		// TODO Auto-generated method stub
		if(event.getTopic().equals(FrigeDeviceImpl.EVENT_TOPIC_ISVALID)){
			if(event.getProperty(FrigeDevice.EVENT_PROPER_ID) != null && event.getProperty(FrigeDevice.EVENT_PROPER_ID).equals(ID)){
				generStateEvent();
			}
		}
		else if(event.getTopic().equals(FrigeSimulateTopic.FRIGE_FOOD_IN) && 
				event.getProperty(FrigeSimulateTopic.PROPER_FOOD_NAME) != null){
			sendInFood(event.getProperty(FrigeSimulateTopic.PROPER_FOOD_NAME).toString());
		}
		else if(event.getTopic().equals(FrigeSimulateTopic.FRIGE_FOOD_OUT) &&
				event.getProperty(FrigeSimulateTopic.PROPER_FOOD_NAME) != null){
			takeOutFood(event.getProperty(FrigeSimulateTopic.PROPER_FOOD_NAME).toString());
		}	
	}
	
	private void generFoodInEvent(String foodName){
		EventAdmin eventAdmin = (EventAdmin) tracker.getService();
		if(eventAdmin != null){
			System.out.println(Calendar.getInstance().getTime().toLocaleString() + 
					" Frige: food in and post event");
			Map<String, String> proper = new Hashtable<String, String>();
			proper.put(FrigeDevice.EVENT_PROPER_FOOD_NAME, foodName);
			Event event = new Event(FrigeDevice.EVENT_TOPIC_FOOD_IN, proper);
			eventAdmin.postEvent(event);
		}	
	}
	
	private void generFoodOutEvent(String foodName){
		EventAdmin eventAdmin = (EventAdmin) tracker.getService();
		if(eventAdmin != null){
			System.out.println(Calendar.getInstance().getTime().toLocaleString() + 
			" Frige: food out and post event");
			Map<String, String> proper = new Hashtable<String, String>();
			proper.put(FrigeDevice.EVENT_PROPER_FOOD_NAME, foodName);
			Event event = new Event(FrigeDevice.EVENT_TOPIC_FOOD_OUT, proper);
			eventAdmin.postEvent(event);
		}	
	}
	
	
	public void sendInFood(String foodName){
		foodInfo.add(foodName);
		//generFoodInEvent(foodName);
		
		generStateEvent();
	}
	
	public void takeOutFood(String foodName){
		if(foodInfo.contains(foodName)){
			foodInfo.remove(foodName);
			//generFoodOutEvent(foodName);
			
			generStateEvent();
		}
	}

	@Override
	public String[] getFoodInfo() {
		// TODO Auto-generated method stub
		if(foodInfo.size() > 0){
			return (String [])foodInfo.toArray(new String[foodInfo.size()]);
		}
		else
			return null;
	}

}
